home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Languages / Masm V6.11 / SAMPLES / DOSDEV / CTEST.C$ / CTEST
Encoding:
Text File  |  1992-11-12  |  5.9 KB  |  214 lines

  1. /*
  2.  * CTEST.C
  3.  *
  4.  * Sample program that uses the Atoms Device Driver (ATMS).
  5.  * The program displays a menu from which you can Write only, Read only,
  6.  * or Quit. Any other key will cause the program to go into the 'Input->
  7.  * Return' mode: It will asked the user for input strings, write them to
  8.  * the device, and immediately read back from the device. To get out of
  9.  * this mode, press return and the menu will come up again
  10.  *
  11.  *    To communicate with the ATMS driver, we first open it as if it were
  12.  * a file, using _sopen. The system will return a handle, with which,
  13.  *    we can begin communicating to the driver.
  14.  *
  15.  *    By passing a null terminated string to _write, you can do the following 
  16.  *        if string =  '<variable>', search for <variable>
  17.  *        if string =  '<variable>=' delete <variable>
  18.  *        if string =  '<variable>=value' insert <variable>
  19.  * This allows us to 'browse' the data stored by ATMS.
  20.  *
  21.  * Calling _read will return the current <variable> text.
  22.  *
  23.  */
  24.  
  25. #include <stdio.h>
  26. #include <dos.h>
  27. #include <share.h>
  28. #include <fcntl.h>
  29.  
  30. #define LENGTH 140                // defining the length of the buffers    
  31. #define inLen LENGTH
  32. #define outLen LENGTH
  33. char InBuffer[LENGTH];          // holds data from keyboard
  34. char OutBuffer[LENGTH];            // holds data from device
  35.   
  36. void     set_raw_mode(int handle),
  37.         display_menu(int handle),
  38.           do_write(int handle),
  39.           do_read(int handle),
  40.           test_result(int value);
  41.  
  42.  
  43. /*
  44.  * main
  45.  *
  46.  * open the device (with sopen, to allow more than one program to open the
  47.  * device at the same time). Set raw mode. Display the menu, allow the user
  48.  * to start there. The infinite loop goes like this: print the input prompt,
  49.  * accept a string from the user. (see do_write below). If count=1, means that
  50.  * only a 'cr' was inputed, so do the menu again. Otherwise, write to the
  51.  * device, first eliminating the last 'cr', and read back from the device.
  52.  * print out what we read from the device. continue the loop.
  53.  */
  54.  
  55. main(int argc, char **argv, char **envp)
  56. {
  57.     int count, handle, index;    /* count holds length of keyboard input string,
  58.                                            handle holds assigned handle to the device */
  59.             
  60.     test_result(handle=_sopen("ATMS",_O_RDWR | _O_BINARY, _SH_DENYNO));
  61.    set_raw_mode(handle);     /* necessary only if not linking to binmode.obj */
  62.  
  63.  
  64.     /* Insert the environment elements */
  65.  
  66.     for (index=0;envp[index]!=NULL;index++)
  67.     {
  68.         printf("%s\n",envp[index]);
  69.         test_result(_write(handle,envp[index],strlen(envp[index])));
  70.     }    
  71.  
  72.     /* Insert the command line arguments */
  73.     
  74.     for (index=1; index<argc; index++)
  75.     {
  76.         printf("%s\n",argv[index]);
  77.         test_result(_write(handle,argv[index],strlen(argv[index])));
  78.     }
  79.  
  80.     display_menu(handle);
  81.  
  82.     for (;;) 
  83.     {
  84.         printf("Input? ");      
  85.         test_result(count=_read(0,OutBuffer,outLen));
  86.         if (count==1)
  87.             display_menu(handle);
  88.         else
  89.             {
  90.                 OutBuffer[--count] = 0;
  91.                 test_result(_write(handle,OutBuffer,outLen));
  92.                 do_read(handle);
  93.             }
  94.     }
  95.  
  96. }
  97.  
  98. /*
  99.  * do_write
  100.  *
  101.  * print the Input prompt. Read from the keyboard. We can't do a scanf
  102.  * because we want to be able to accept white space in the variable values
  103.  * then set the last character of the buffer (which would be a carriage 
  104.  * return, to be null terminated, a 0. If we didn't do that, then variable
  105.  * values would finish with a cr, as would variable names in a search.
  106.  * finally, write the result to the device
  107.  */
  108.  
  109. void do_write(int handle)
  110. {
  111.     int count;
  112.  
  113.     printf("Input? ");      
  114.     test_result(count=_read(0,OutBuffer,outLen));
  115.     OutBuffer[--count] = 0;
  116.     test_result(_write(handle,OutBuffer,outLen));
  117. }
  118.  
  119. /*
  120.  * do_read
  121.  *
  122.  *    read from the device into the InBuffer, which has inLen.
  123.  * count will hold the actual number of bytes transferred.
  124.  * print the input buffer out. since count from read include the '\0',
  125.  * decrement count before printing it.
  126.  */
  127.  
  128. void do_read(int handle)
  129. {
  130.     int count;
  131.     
  132.     test_result(count=_read(handle,InBuffer,inLen));
  133.     printf("\nReturn(%d): %s\n\n",--count,InBuffer);
  134. }
  135.  
  136. /*
  137.  *    display_menu
  138.  *
  139.  * Displays the simple menu, waits for a character. If 1 or 2, do a Write or
  140.  * a Read only. 0 closes the device and quits. Any other key, return
  141.  */
  142.  
  143. void display_menu(int handle)
  144. {
  145.     static char *menu ="\n\tATMS device driver Sample\n\tSelect Device Function\
  146. \n\n\t1. Write to Device Only\n\t2. Read from Device Only\n\t0. Quit\n\
  147. \tOther Keys: Write & Read\n\t\t    Until Return\n";
  148.     char ch;
  149.  
  150.     printf("%s",menu);
  151.  
  152.     for (;;)
  153.     {
  154.     printf("\n      Please press a key: ");
  155.     ch=getch();
  156.     printf("%c \n\n",ch);
  157.     switch (ch)
  158.         {
  159.           case '0':
  160.                 test_result(_close(handle));
  161.                 exit(0);
  162.                 break;
  163.              case '1':
  164.                 do_write(handle);
  165.                 break;
  166.              case '2':
  167.                 do_read(handle);
  168.                 break;
  169.             default:
  170.                 return;
  171.         }
  172.     }
  173. }
  174.  
  175. /* 
  176.  * test_result
  177.  *
  178.  * since there are so many places that error-checking has to be performed,
  179.  * calling this routine automatically does it, and if there's an error it
  180.  * displays the error string, and exits the program
  181.  */
  182.  
  183. void test_result(int value)
  184. {
  185.     if (value == -1)                    // a value of -1 always indicates error
  186.         {
  187.             perror("ATMS Error");    // using perror display a user-friendly string
  188.             exit(value);
  189.         }
  190. }
  191.  
  192. /*
  193.  * set_raw_mode
  194.  *
  195.  * cooked (sometimes called text) mode send data to the device one character
  196.  * at a time. we need to be in raw mode. a low-level interrupt accomplishes 
  197.  * this. this is also an example of how to use DOS interrupts in your code
  198.  * the definitions for this routine are in dos.h
  199.  * 
  200.  * this is faster and smaller than linking with binmode.obj
  201.  */ 
  202.  
  203. void set_raw_mode(int handle)
  204. {
  205.     union REGS regs;
  206.  
  207.     regs.x.ax=0x4401;                    // set to function 0x4401: Set Device Data
  208.     regs.x.bx=handle;                    // bx has the handle of the device
  209.     regs.x.dx=0x00a0;                    // dx sets bits 7 & 5: device + raw mode
  210.     intdos(®s,®s);                // do the interrupt with the registers in regs
  211.                                             // and the output will also be in regs.    
  212. }
  213.  
  214.